package io.yuncheng.modules.sys.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.yuncheng.common.config.DictConfig;
import io.yuncheng.common.utils.*;
import io.yuncheng.modules.sys.entity.AgentArithmeticStepCollectEntity;
import io.yuncheng.modules.sys.entity.SubAppAlgorithmLogCollectArithTimeEntity;
import io.yuncheng.modules.sys.entity.SubAppLogCollectEntity;
import io.yuncheng.modules.sys.entity.SubApplicationEntity;
import io.yuncheng.modules.sys.service.SubAppAlgorithmLogCollectArithTimeService;
import io.yuncheng.modules.sys.service.SubAppLogCollectService;
import io.yuncheng.modules.sys.service.SubApplicationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.yuncheng.common.utils.DateUtils;
import io.yuncheng.common.utils.NumberUtil;
import io.yuncheng.common.utils.SysDictConstant;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 算法日志次数时间汇总
 *
 * @author jared
 * @email 15721509625@163.com
 * @date 2020-10-29 18:50:09
 */
@RestController
@Api(tags = "密码汇总统计")
@RequestMapping("sys/subappalgorithmlogcollectarithtime")
public class SubAppAlgorithmLogCollectArithTimeController {
    @Autowired
    private SubAppAlgorithmLogCollectArithTimeService subAppAlgorithmLogCollectArithTimeService;
    @Autowired
    private SubApplicationService subApplicationService;
    @Resource
    private SubAppLogCollectService subAppLogCollectService;
    @Resource
    DictConfig dictConfig;

    /**
     * 列表
     */
    @PostMapping("/list")
    @RequiresPermissions("sys:subappalgorithmlogcollectarithtime:list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = subAppAlgorithmLogCollectArithTimeService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @GetMapping("/info/{id}")
    @RequiresPermissions("sys:subappalgorithmlogcollectarithtime:info")
    public R info(@PathVariable("id") Long id) {
        SubAppAlgorithmLogCollectArithTimeEntity subAppAlgorithmLogCollectArithTime = subAppAlgorithmLogCollectArithTimeService.getById(id);

        return R.ok().put("subAppAlgorithmLogCollectArithTime", subAppAlgorithmLogCollectArithTime);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    @RequiresPermissions("sys:subappalgorithmlogcollectarithtime:save")
    public R save(@RequestBody SubAppAlgorithmLogCollectArithTimeEntity subAppAlgorithmLogCollectArithTime) {
        subAppAlgorithmLogCollectArithTimeService.save(subAppAlgorithmLogCollectArithTime);

        return R.ok();
    }

    /**
     * 修改
     */
    @PostMapping("/update")
    @RequiresPermissions("sys:subappalgorithmlogcollectarithtime:update")
    public R update(@RequestBody SubAppAlgorithmLogCollectArithTimeEntity subAppAlgorithmLogCollectArithTime) {
        subAppAlgorithmLogCollectArithTimeService.updateById(subAppAlgorithmLogCollectArithTime);

        return R.ok();
    }

    /**
     * 删除
     */
    @PostMapping("/delete")
    @RequiresPermissions("sys:subappalgorithmlogcollectarithtime:delete")
    public R delete(@RequestBody Long[] ids) {
        subAppAlgorithmLogCollectArithTimeService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    /**
     * 列表
     */
    @PostMapping("/list-collect-old")
    @ApiOperation("查询次数汇总")
    public R collectByDate(Long deptId,Date start, Date end) {
        Long appId = null;
        if(deptId!=null){
            SubApplicationEntity subApplicationEntity = subApplicationService.queryByDeptId(deptId);
            if(subApplicationEntity!=null){
                appId = subApplicationEntity.getAppId();
            }
        }
        QueryWrapper<SubAppAlgorithmLogCollectArithTimeEntity> query = new QueryWrapper<SubAppAlgorithmLogCollectArithTimeEntity>().ge(start!=null,"log_date", start).lt(end!=null,"log_date", end).eq(appId!=null,"app_id", appId).orderByAsc("log_date");
        List<SubAppAlgorithmLogCollectArithTimeEntity> list = subAppAlgorithmLogCollectArithTimeService.list(query);
        //调用总次数趋势
        Map<String, Integer> allYearTotal = list.stream().collect(Collectors.groupingBy(SubAppAlgorithmLogCollectArithTimeEntity::formatYearLogDate,LinkedHashMap::new, Collectors.summingInt(SubAppAlgorithmLogCollectArithTimeEntity::allAlgorithmCount)));
        Map<String, Integer> allMonthTotal = list.stream().collect(Collectors.groupingBy(SubAppAlgorithmLogCollectArithTimeEntity::formatMonthLogDate,LinkedHashMap::new, Collectors.summingInt(SubAppAlgorithmLogCollectArithTimeEntity::allAlgorithmCount)));
        R ok = R.ok();
        SubAppAlgorithmLogCollectArithTimeEntity total = new SubAppAlgorithmLogCollectArithTimeEntity();
        list.forEach(a-> NumberUtil.addEntityParentChild(total,a));
        Map<Integer, Integer> integerMap = NumberUtil.buildMapByTimeEntity(total);
        ok.put("allYearTotal",allYearTotal);
        ok.put("allMonthTotal",allMonthTotal);
        ok.put("percent",integerMap);

        ok.put("avgTime",NumberUtil.buildAvgTime(total));

        //单个占比
        //趋势
        Map<String, List<SubAppAlgorithmLogCollectArithTimeEntity>> yearEntity = list.stream().collect(Collectors.groupingBy(SubAppAlgorithmLogCollectArithTimeEntity::formatYearLogDate,LinkedHashMap::new,Collectors.toList()));
        Map<String, Map> year = mapListToMapArith(yearEntity);
        Map<String, List<SubAppAlgorithmLogCollectArithTimeEntity>> monthEntity = list.stream().collect(Collectors.groupingBy(SubAppAlgorithmLogCollectArithTimeEntity::formatMonthLogDate,LinkedHashMap::new,Collectors.toList()));
        Map<String, Map> month = mapListToMapArith(monthEntity);
        ok.put("yearArith",year);
        ok.put("monthArith",month);
        return ok;
    }
    /**
     * 列表
     */
    @PostMapping("/list-collect")
    @ApiOperation("查询次数汇总")
    public R collectByDateNew(Long deptId,Date start, Date end) {
        Long appId = -1L;
        if(deptId!=null){
            SubApplicationEntity subApplicationEntity = subApplicationService.queryByDeptId(deptId);
            if(subApplicationEntity!=null){
                appId = subApplicationEntity.getAppId();
            }
        }
        //查询日志
        QueryWrapper<SubAppLogCollectEntity> query = new QueryWrapper<SubAppLogCollectEntity>().ge(start!=null,"log_date", start).lt(end!=null,"log_date", end).eq(appId!=null,"app_id", appId).orderByAsc("log_date");
        List<SubAppLogCollectEntity> list = subAppLogCollectService.list(query);

        Map<Date, List<SubAppLogCollectEntity>> monthList = list.stream().collect(Collectors.groupingBy(SubAppLogCollectEntity::buildByMonth,LinkedHashMap::new,Collectors.toList()));


        Map<Date,Map<String , AgentArithmeticStepCollectEntity>> monthMap = new LinkedHashMap<>(16);
        Map<String,Map<String ,Long>> monthArith = new LinkedHashMap<>(16);
       Map<String ,Long> allMonthTotal = new LinkedHashMap<>(16);
        Map<String ,AgentArithmeticStepCollectEntity> allEntity = new LinkedHashMap<>(4);

        for (Map.Entry<Date, List<SubAppLogCollectEntity>> entity : monthList.entrySet()) {
            //汇总明细
            Map<String ,AgentArithmeticStepCollectEntity> map = new LinkedHashMap<>(4);
            entity.getValue().forEach(a->{
                List<AgentArithmeticStepCollectEntity> step = JSON.parseObject(a.getStepArithTime(), new TypeReference<List<AgentArithmeticStepCollectEntity>>() {});
                for (AgentArithmeticStepCollectEntity stepCollectEntity : step) {
                    buildMapAdd(map,stepCollectEntity);
                    buildMapAdd(allEntity,stepCollectEntity);
                }
            });
            //汇总月份
            Long monthTotal = 0L;
            Map<String ,Long> longMap = new LinkedHashMap<>(4);
            for (Map.Entry<String, AgentArithmeticStepCollectEntity> stringAgentArithmeticStepCollectEntityEntry : map.entrySet()) {
                String sysDictCode = dictConfig.getSysDictCode(SysDictConstant.ARITH, stringAgentArithmeticStepCollectEntityEntry.getKey());
                longMap.put(sysDictCode,stringAgentArithmeticStepCollectEntityEntry.getValue().getAlgoCount());
                monthTotal = NumberUtil.longAdd(monthTotal, stringAgentArithmeticStepCollectEntityEntry.getValue().getAlgoCount());
            }
            allMonthTotal.put(io.yuncheng.common.utils.DateUtils.formatMonth(entity.getKey()),monthTotal);
            monthArith.put(io.yuncheng.common.utils.DateUtils.formatMonth(entity.getKey()),longMap);
            monthMap.put(entity.getKey(),map);
        }

        Map<String ,Long> percentMap = new HashMap<>(4);
        Map<String ,Long> avgMap = new HashMap<>(4);

        for (Map.Entry<String, AgentArithmeticStepCollectEntity> stringAgentArithmeticStepCollectEntityEntry : allEntity.entrySet()) {
            String sysDictCode = dictConfig.getSysDictCode(SysDictConstant.ARITH, stringAgentArithmeticStepCollectEntityEntry.getKey());
            percentMap.put(sysDictCode,stringAgentArithmeticStepCollectEntityEntry.getValue().getAlgoCount());
            BigDecimal percentTimeCount = NumberUtil.getPercentTimeCount(stringAgentArithmeticStepCollectEntityEntry.getValue().getTimeSpan(), stringAgentArithmeticStepCollectEntityEntry.getValue().getAlgoCount().intValue());
            avgMap.put(sysDictCode,percentTimeCount.longValue());
        }
      Map<String,Long> allArithType = new HashMap<>();
        for (Map.Entry<String, Map<String, Long>> stringMapEntry : monthArith.entrySet()) {
            for (Map.Entry<String, Long> stringLongEntry : stringMapEntry.getValue().entrySet()) {
                boolean b = allArithType.containsKey(stringLongEntry.getKey());
                if(b){
                    allArithType.put(stringLongEntry.getKey(),NumberUtil.longAdd(stringLongEntry.getValue(),allArithType.get(stringLongEntry.getKey())));
                }else{
                    allArithType.put(stringLongEntry.getKey(),stringLongEntry.getValue());
                }
            }

        }
        R ok = R.ok();
        ok.put("monthArith",monthArith);
        ok.put("allArithType",allArithType);
        ok.put("percent",percentMap);
        ok.put("avgTime",avgMap);

        //组装年份数据
        Map<Date, List<SubAppLogCollectEntity>> year = list.stream().collect(Collectors.groupingBy(SubAppLogCollectEntity::buildByYear,LinkedHashMap::new,Collectors.toList()));
        Map<Date,Map<String ,AgentArithmeticStepCollectEntity>> yearMap = new LinkedHashMap<>(16);
        Map<String,Map<String ,Long>> yearLongMap = new LinkedHashMap<>(16);
        Map<String ,Long> allYearTotal = new LinkedHashMap<>(4);

        for (Map.Entry<Date, List<SubAppLogCollectEntity>> dateListEntry : year.entrySet()) {
            Map<String ,AgentArithmeticStepCollectEntity> map = new LinkedHashMap<>(4);
            dateListEntry.getValue().forEach(a->{
                List<AgentArithmeticStepCollectEntity> step = JSON.parseObject(a.getStepArithTime(), new TypeReference<List<AgentArithmeticStepCollectEntity>>() {});
                for (AgentArithmeticStepCollectEntity stepCollectEntity : step) {
                    buildMapAdd(map,stepCollectEntity);
                }

            });
            Map<String ,Long> longMap = new LinkedHashMap<>(4);
            Long yearTotal = 0L;
            for (Map.Entry<String, AgentArithmeticStepCollectEntity> stringAgentArithmeticStepCollectEntityEntry : map.entrySet()) {
                String sysDictCode = dictConfig.getSysDictCode(SysDictConstant.ARITH, stringAgentArithmeticStepCollectEntityEntry.getKey());
                longMap.put(sysDictCode,stringAgentArithmeticStepCollectEntityEntry.getValue().getAlgoCount());
                yearTotal = NumberUtil.longAdd(yearTotal,stringAgentArithmeticStepCollectEntityEntry.getValue().getAlgoCount());
            }
            allYearTotal.put(io.yuncheng.common.utils.DateUtils.formatYear(dateListEntry.getKey()),yearTotal);
            yearLongMap.put(io.yuncheng.common.utils.DateUtils.formatYear(dateListEntry.getKey()),longMap);
            yearMap.put(dateListEntry.getKey(),map);
        }


        ok.put("yearArith",yearLongMap);
        ok.put("allMonthTotal",allMonthTotal);
        ok.put("allYearTotal",allYearTotal);


        return ok;
    }
    public void  buildMapAdd( Map<String ,AgentArithmeticStepCollectEntity> map,AgentArithmeticStepCollectEntity stepCollectEntity){
        AgentArithmeticStepCollectEntity arithStep = map.get(stepCollectEntity.getStepAlgo());
        if(arithStep != null){
            arithStep.addValue(stepCollectEntity);
        }else{
            AgentArithmeticStepCollectEntity  stepTemp = new AgentArithmeticStepCollectEntity();
            stepTemp.setAlgoCount(stepCollectEntity.getAlgoCount());
            stepTemp.setTimeSpan(stepCollectEntity.getTimeSpan());
            stepTemp.setStepAlgo(stepCollectEntity.getStepAlgo());
            map.put(stepTemp.getStepAlgo(),stepTemp);
        }
    }

    @PostMapping("/list-collect-last-year")
    @ApiOperation("查询次数汇总")
    public R collectLastYear(Long deptId) {
        Date dayFirstDate = io.yuncheng.common.utils.DateUtils.getDayFirstDate(new Date());
        R r = collectByDateNew(deptId, DateUtils.getLastYear(dayFirstDate), dayFirstDate);
        return r;
    }

    public Map<String,Map> mapListToMapArith(Map<String, List<SubAppAlgorithmLogCollectArithTimeEntity>> yearEntity){
        Map<String,Map> yearMap = new LinkedHashMap<>(16);
        for (Map.Entry<String, List<SubAppAlgorithmLogCollectArithTimeEntity>> stringListEntry : yearEntity.entrySet()) {
            SubAppAlgorithmLogCollectArithTimeEntity year = new SubAppAlgorithmLogCollectArithTimeEntity();
            stringListEntry.getValue().forEach(a->NumberUtil.addEntityParentChild(year,a));
            yearMap.put(stringListEntry.getKey(), NumberUtil.buildMapByTimeEntity(year));
        }
        return yearMap;
    }

}
